package simulation;

import java.util.ArrayList;

/**
 * 空间类。存放门，空间的边界，在该空间内的学生。
 */
public class Space {
    private final double up;
    private final double down;
    private final double left;
    private final double right;
    private final ArrayList<Student> students = new ArrayList<>();
    private Door door;

    public ArrayList<Student> getStudents() {
        return students;
    }

    public void setDoor(Door door) {
        this.door = door;
    }

    public double getUp() {
        return up;
    }

    public double getDown() {
        return down;
    }

    public double getLeft() {
        return left;
    }

    public double getRight() {
        return right;
    }

    public void addStudent(Student student) {
        students.add(student);
    }

    public void deleteStudent(Student student) {
        students.remove(student);
    }

    public Space(double up, double down, double left, double right) {
        this.up = up;
        this.down = down;
        this.left = left;
        this.right = right;
    }

    public Door getDoor() {
        return this.door;
    }

    public double getRandomX(){
        return MathUtil.randomDouble(left + 4, right - 4);
    }

    public double getRandomY(){
        return MathUtil.randomDouble(down - 4, up + 4);
    }

    public boolean inSpace(double x, double y) {
        return x < right - 4 && x > left + 4 &&
                y <down - 4 && y > up + 4;
    }

    /**
     * 对space的students遍历，对每个和感染者的距离小于dangerous distance的人进行判定，按照感染率进行感染。
     * O(n^2)的复杂度，通过将学生分到不同的space减小数量规模
     */
    public void infect() {
            for (Student eum:students) {
                if (eum.getState() == State.INFECTED) {
                    eum.toSymptomatic();
                }
                else if (eum.getState() == State.SYMPTOMATIC) {
                    eum.toRecover();
                }
            }
    }
    private int toInfected(Student eum){
        int num =0;
        for (Student stu:students) {
            if (stu.getState() == State.HEALTHY)
                if (MathUtil.distanceOfStudent(eum, stu) < GlobalVar.DANGEROUS_DISTANCE)
                    if (MathUtil.randomDouble(0,1) < GlobalVar.INFECTION_RATE) {
                        stu.toInfected();
                        num++;
                    }
        }
        return num;
    }
}
